package com.chinaway.dsp.conn;

import java.net.InetSocketAddress;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import com.chinaway.dsp.action.BackAction;
import com.chinaway.dsp.action.IteratorSendAction;
import com.chinaway.dsp.util.AccStatus;
import com.chinaway.dsp.util.CountBean;


public class TestConn{
	private Text log_info;
	public static ConnectFuture cf=null;
	static NioSocketConnector connector =null;
	IoSession session=null;
	LoggingFilter lf=new LoggingFilter();
	ByteArrayCodecFactory bacf=new ByteArrayCodecFactory ();
	ProtocolCodecFilter pcf=new ProtocolCodecFilter(bacf);
	ServerResponse sr;
	List<?> dataList =null;
	private Display display;
	private Shell shell;
	private Button connbtn;
	private Button send_stop_btn;
	private Button send_iteration_btn;
	private Button acc_status_btn;
	private int sendCount=1;
	List<String> list_7d7e = new ArrayList<String>();
	SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private CountBean cb;
	public IteratorSendAction iteratorSendAction;
	public BackAction bacAction;
	public AccStatus accStatus;
	
	public TestConn(Text t){
		log_info=t;
	}
	
	public void setDataList(List<?> l){
		dataList=l;
	}
	
	public void setDisplay(Display d){
		display=d;
	}
	
	public void setShell(Shell s){
		shell=s;
	}
	
	public void setConnBtn(Button b){
		connbtn=b;
	}
	
	public void setSend_Stop_Btn(Button b){
		send_stop_btn=b;
	}
	
	public void setSend_Iteration_Btn(Button b){
		send_iteration_btn=b;
	}
	
	public void setAcc_Status_Btn(Button b){
		acc_status_btn=b;
	}
	
	public void setCountBean(CountBean c){
		this.cb=c;
	}
	
	public ServerResponse getSr(){
		return this.sr;
	}
	
	public void setBackAction(BackAction ba){
		bacAction=ba;
	}
	
	public void setAccStatus(AccStatus as){
		this.accStatus=as;
	}
	
	public boolean conn(String ip,int port){
		sr=new ServerResponse(display,shell,connbtn,log_info,cb,send_stop_btn,send_iteration_btn);
		boolean flag=false;
		connector= new NioSocketConnector();
		connector.setConnectTimeoutMillis(10000);
//		connector.getFilterChain().addLast("logger", lf);
		connector.getFilterChain().addLast("codec",	pcf); // 设置编码过滤器
		connector.setHandler(sr);// 设置事件处理器10.3.30.128，172.16.1.13,172.16.1.45,172.16.1.44
		cf = connector.connect(new InetSocketAddress(ip,port));// 建立连接"120.55.106.116",966
		cf.awaitUninterruptibly();// 等待连接创建完成
		flag=cf.isConnected();
		if(flag){
			session = cf.getSession();
			bacAction.setSendSession(session);
		}
		return flag;
	}
	
	public boolean reconn(String ip,int port){
		boolean flag=false;
		connector= new NioSocketConnector();
		connector.setConnectTimeoutMillis(10000);
//		connector.getFilterChain().addLast("logger", lf);
		connector.getFilterChain().addLast("codec",	pcf); // 设置编码过滤器
		connector.setHandler(sr);// 设置事件处理器10.3.30.128，172.16.1.13,172.16.1.45,172.16.1.44
		cf = connector.connect(new InetSocketAddress(ip,port));// 建立连接"120.55.106.116",966
		cf.awaitUninterruptibly();// 等待连接创建完成
		flag=cf.isConnected();
		if(flag){
			session = cf.getSession();
			bacAction.setSendSession(session);
		}
			
		return flag;
	}
	
	public void customSend(String msg){
		String tmp[]=msg.split(" ");
		byte[] mes = AssemblyPacket.transfer2Bytes(msg);
		if("0900".equals(tmp[1]+tmp[2]))
			ctboxFlag(mes);
		else
			setNewFlag(mes);
		byte[] message=AssemblyPacket.edit7d7e(mes);
		session.write(message);
		String send=AssemblyPacket.byteToString(message);
		System.out.println("msg="+send);
		Date currentTime = new Date();
	 	String dateString = formatter.format(currentTime);
		log_info.append(dateString+" 发送：\n"+send+"\n");
		sendCount++;
	}
	
	public void send(String sendtype,String totaltime,String iterationtime,int devicetype,String imei,int acc,String gpstime,String lng,String lat,String speed,String course){
		if(0==devicetype)
			smartSend(sendtype,totaltime,iterationtime,imei,gpstime,acc,lng,lat,speed,course);
		if(1==devicetype)
			gnnsSend(sendtype,totaltime,iterationtime,imei,gpstime,acc,lng,lat,speed,course);
	}
	
	public void smartSend(String sendtype,String totaltime,String iterationtime,String imei,String gpstime,int acc,String lng,String lat,String speed,String course){
		if(lng.length()==0)
			lng="104.072227";
		if(lat.length()==0)
			lat="30.663468";
		
		String msg_acc=AssemblyPacket.toAcc(acc);
		String msg_speed=AssemblyPacket.toSpeed(speed);
		String msg_course=AssemblyPacket.toCourse(course);
		String msg_imei=AssemblyPacket.toImei(imei);
		String msg_gpstime=AssemblyPacket.toGpsTime(gpstime);
		String msg_seq=AssemblyPacket.string2wordhex(String.valueOf(sendCount));
		String msg_lng=AssemblyPacket.toLngLat(lng);
		String msg_lat=AssemblyPacket.toLngLat(lat);
		
		
		if("".equals(sendtype)){
			IteratorSendAction isa=new IteratorSendAction(session,display,log_info,msg_imei,msg_speed,msg_course,msg_lng,msg_lat,totaltime,iterationtime,0,accStatus,send_iteration_btn,acc_status_btn);
			this.iteratorSendAction=isa;
			sr.setIsa(isa);
			Thread iteratorSendAction=new Thread(isa);
			iteratorSendAction.start();
		}else{
			String msg="7E 05 00 00 27 "+msg_imei+" "+msg_seq+" 1D "+msg_acc+" "+msg_lat+" "+msg_lng+" 00 00 "+msg_speed+" "+msg_course+" "+msg_gpstime+" 00 00 00 00 00 0E 08 30 00 01 BA 53 70 4C 11 C0 B9 7E";
			System.out.println(msg);
			byte[] mes = AssemblyPacket.transfer2Bytes(msg);
			setNewFlag(mes);
			byte[] message=AssemblyPacket.edit7d7e(mes);
			session.write(message);
			String send=AssemblyPacket.byteToString(message);
			Date currentTime = new Date();
		 	String dateString = formatter.format(currentTime);
			log_info.append(dateString+" 发送：\n"+send+"\n");
			sendCount++;
		}
	}
	
	public void gnnsSend(String sendtype,String totaltime,String iterationtime,String imei,String gpstime,int acc,String lng,String lat,String speed,String course){
		if(lng.length()==0)
			lng="104.072227";
		if(lat.length()==0)
			lat="30.663468";
		
		String msg_acc=AssemblyPacket.toGnnsAcc(acc);
		String msg_speed=AssemblyPacket.toSpeed(speed);
		String msg_course=AssemblyPacket.toCourse(course);
		String msg_imei=AssemblyPacket.toImei(imei);
		String msg_gpstime=AssemblyPacket.toGpsTime(gpstime);
		String msg_seq=AssemblyPacket.string2wordhex(String.valueOf(sendCount));
		String msg_lng=AssemblyPacket.toLngLat(lng);
		String msg_lat=AssemblyPacket.toLngLat(lat);
		
		if("".equals(sendtype)){
			IteratorSendAction isa=new IteratorSendAction(session,display,log_info,msg_imei,msg_speed,msg_course,msg_lng,msg_lat,totaltime,iterationtime,1,accStatus,send_iteration_btn,acc_status_btn);
			this.iteratorSendAction=isa;
			sr.setIsa(isa);
			Thread iteratorSendAction=new Thread(isa);
			iteratorSendAction.start();
		}else{
			String msg="7E 02 00 00 1C "+msg_imei+" "+msg_seq+" 00 00 00 00 "+msg_acc+" "+msg_lat+" "+msg_lng+" 00 00 "+msg_speed+" "+msg_course+" "+msg_gpstime+" B9 7E";
			byte[] mes = AssemblyPacket.transfer2Bytes(msg);
			setNewFlag(mes);
			byte[] message=AssemblyPacket.edit7d7e(mes);
			session.write(message);
			String send=AssemblyPacket.byteToString(message);
			Date currentTime = new Date();
		 	String dateString = formatter.format(currentTime);
			log_info.append(dateString+" 发送：\n"+send+"\n");
			sendCount++;
		}
	}
	
	public void close(){
		if(null!=cf){
			session.close(true);
			connector.dispose();
		}
		
	}
	
	private void ctboxFlag(byte[] bs){
		byte[] da = new byte[bs.length - 15];
		System.arraycopy(bs, 13, da, 0, da.length);
		//ctbox校验位
		bs[bs.length - 4] = setNewFlagSub(da);
		//然后gnns校验位
		int idx = bs.length - 2;  
		bs[idx] = bs[1];
		for (int j=2;j<idx;j++) bs[idx] ^= bs[j];
	}
	
	private void setNewFlag(byte[] bs) {
		byte[] da = new byte[bs.length - 15];
		System.arraycopy(bs, 13, da, 0, da.length);
		int idx = bs.length - 2;  
		bs[idx] = bs[1];
		for (int j=2;j<idx;j++) 
			bs[idx] ^= bs[j];
	}
	private static byte setNewFlagSub(byte[] da) {
		byte flag = da[1];// 从数据头开始
		for (int i = 2; i < da.length - 2; i++) {
			flag ^= da[i];
		}
		// 校验码
		return flag;
	}
}
